
var net = require('net');
var actorify = require('./roleactor.js');
var async = require('async');

var MODNAME = 'stackclient';
/**
 * stacks client object prototype
 *
 * @api private
 */
function StacksClient(pParentObj) {
  var client = {};
  client._actor = null;
  client._connection = null;
  client._isConnected = false;
  client._queues = {};
  
  MODNAME = pParentObj._modname + '_' + MODNAME;
  client.logger = pParentObj.logger;

  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'new instance is created');

  /**
   * connect to server
   * 
   * @api public
   * @param <Mixed> server
   * @param <Function> callback
   */
  client.connect = function connect(server, callback) {
	 
	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'connecting server...');

    client._connection = net.connect(server, function() {
  	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'connected to server successfully...');
      
      client._actor = actorify(client._connection);

      /**
       * handle stacks request of type |type| with worker |worker|
       * allow |concurrency| concurrent workers
       *
       * @api public
       * @param <String> type
       * @param <Function> worker
       * @param <Number> concurrency
       */
      client.on = function on(type, worker, concurrency) {
    	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'create queue for requests of type: '+ type);
    	  
    	  client._queues[type] = async.queue(worker, concurrency);

        client._actor.on(type, function(body, reply) {
      	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'received stacks request of type '+type+'; with body: ' + JSON.stringify(body));
          client._queues[type].push(body, reply);
        });
      };

      /**
       * debug messages for socket events
       */
     
      client._connection.on('end', function() {
    	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'socket end...');
      });
      client._connection.on('close', function() {
    	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'socket closed...');
      });     
      
      client._isConnected = true;
      callback(null, client);
    });
    
    client._connection.on('error', function(error) {
    	client.logger.log(MODNAME, 'INFO_LEVEL_4', 'socket error: ' + error.message);
        callback(error, null);
      });
    client._connection.on('timeout', function() {
    	client.logger.log(MODNAME, 'INFO_LEVEL_4', 'socket timeout...');
        var error = new Error();
//    	console.log("Error :" + err.stack);
//    	console.log("Error :" + err.lineNumber);
        error.message = 'Connection request timeout';
        callback(error, null);

      });
  };

  /**
   * disconnect stacks client
   *
   * @api public
   */
  client.disconnect = function disconnect() {
	  	  
	  client.logger.log(MODNAME, 'INFO_LEVEL_4', 'disconecting...');
	  client._connection.end();
	  client.removeClient();	  
  };

  /**
   * expose public api
   */
  this.connect = client.connect;
  this.disconnect = client.disconnect;
};

module.exports = StacksClient;